package com.yf.service.impl;

import com.google.code.kaptcha.Producer;
import com.yf.dao.AccountDao;
import com.yf.entity.*;
import com.yf.enums.UserStatusEnum;
import com.yf.response.R;
import com.yf.response.RRException;
import com.yf.service.*;
import com.yf.vo.UserBackVo;
import com.yf.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

import com.yf.dao.UserDao;
import com.yf.service.impl.BaseServiceImpl;
import org.springframework.transaction.annotation.Transactional;
//import sun.tools.jstat.Token;

/**
 * 用户Service实现类
 *
 * @author hxf
 * @email 505860922@qq.com
 * @date Tue Aug 21 10:46:07 CST 2018
 */
@Service
@Slf4j
public class UserServiceImpl extends BaseServiceImpl<UserEntity> implements UserService {
    @Autowired
    private UserDao userDao;

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private Producer producer;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 内部方法
     **/

    private String getPath(UserEntity parent) {
        if (parent.getPath() == null) {
            return String.valueOf(parent.getId());
        }
        return parent.getPath() + "/" + parent.getId();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public TokenEntity registerUser(String phone, String password, String name, String uuid, String captcha, String parentPhone) {
        String captchaTem = (String) redisTemplate.opsForValue().get(uuid);
        if (!captchaTem.equals(captcha)) {
            throw new RRException("验证码错误!");
        }
        //移除验证码
        redisTemplate.opsForValue().getOperations().delete(uuid);
        UserEntity userEntity = new UserEntity(name,phone,password);
        //设置
        if(!StringUtils.isBlank(parentPhone)){
            UserEntity parent = userDao.findByAccount(parentPhone);
            if(parent==null){
                throw new RRException(parentPhone+"不存在此用户");
            }
            userEntity.setParentId(parent.getId());
        }
        userDao.save(userEntity);
        //TODO 创建账户等等
        return tokenService.createToken(userEntity.getId());
    }

    /**
     * 外部方法实现
     **/


    @Override
    @Transactional(rollbackFor = Exception.class)
    public TokenEntity registerUser(WxUser wxUser, Long parentId) {
        //上级信息
        UserEntity parent = get(parentId);
        if (parent == null) {
            log.error("注册失败，parentId不存在:" + parentId);
            throw new RRException("推荐人不存在!ID:" + parentId);
        }
        //初始时间
        Date date = new Date();
        //初始级别
        LevelEntity levelEntity = levelService.getInitUserLevel();
        UserEntity userEntity = new UserEntity(levelEntity.getId(), wxUser.getNickName(), wxUser.getHeadImgUrl(), wxUser.getSex(), wxUser.getOpenId(), wxUser.getUnionId(), parentId, date, date, date, UserStatusEnum.ACTIVE.getState(), getPath(parent));
        userDao.save(userEntity);
        //创建Account
        AccountEntity accountEntity = new AccountEntity(userEntity.getId(), new BigDecimal(0.0), 0L, new BigDecimal(0.0), userEntity.getName(), userEntity.getAvatar());
        accountDao.save(accountEntity);
        //返回token
        return tokenService.createToken(userEntity.getId());
    }


    @Override
    @Transactional
    public UserEntity completeUserInfo(UserEntity userEntity, String name, String info, String phone, String qrcode) {
        if (!StringUtils.isBlank(name)) {
            userEntity.setName(name);
        }
        if (!StringUtils.isBlank(info)) {
            userEntity.setInfo(info);
        }
        if (!StringUtils.isBlank(phone)) {
            userEntity.setPhone(phone);
        }
        if (!StringUtils.isBlank(qrcode)) {
            userEntity.setQrcode(qrcode);
        }
        userDao.update(userEntity);
        return userEntity;
    }

    @Override
    @Transactional
    public TokenEntity validateLogin(UserEntity userEntity) {
        if (userEntity == null) {
            throw new RRException("账户不存在!");
        }
        if (!userEntity.getStatus().equals(UserStatusEnum.ACTIVE.getState())) {
            throw new RRException("用户没有激活!");
        }
        return tokenService.createToken(userEntity.getId());
    }

    @Override
    public UserEntity findByUnionId(String unionId) {
        List<UserEntity> list = userDao.findByUnionId(unionId);
        if (list == null || list.isEmpty()) {
            return null;
        }
        if (list.size() > 1) {
            log.error("账号异常unionId不唯一:" + unionId);
            throw new RRException(unionId + "账号不唯一");
        }
        return list.get(0);
    }

    @Override
    public List<UserEntity> findDownByTree(UserEntity userEntity) {
        return userDao.findDownByTree(userEntity.getPath());
    }

    @Override
    public List<UserEntity> findUpByTree(UserEntity userEntity) {
        return userDao.findUpByTree(userEntity.getPath().split("/"));
    }

    @Override
    public List<UserEntity> findDown(UserEntity userEntity) {
        return userDao.findDown(userEntity.getId());
    }


    /**
     * 更换上级 更换路径 以及下面的路径
     *
     * @param entity
     * @param parent
     */
    @Transactional
    public void updateParent(UserEntity entity, UserEntity parent) {
        String oldPath = getPath(entity);
        entity.setParentId(parent.getId());
        entity.setPath(getPath(parent));
        String newPath = getPath(entity);
        //保存当前用户
        userDao.update(entity);
        //更新下级路径
        userDao.updateDownPath(oldPath, newPath);
    }


    @Override
    public BufferedImage createImageCaptcha(String uuid) {
        String text = producer.createText();
        //存储到Redis 保持五分钟
        redisTemplate.opsForValue().set(uuid, text, 5, TimeUnit.MINUTES);
        BufferedImage image = producer.createImage(text);
        return image;
    }

    @Override
    public void createPhoneCaptcha(String uuid, String phone) {
        String text = producer.createText();
        //存储到Redis 保持五分钟
        redisTemplate.opsForValue().set(uuid, text, 5, TimeUnit.MINUTES);
        //TODO 手机发送这个验证码
    }

    @Override
    public UserEntity loginByPassword(String phone, String password, String uuid, String captcha) {
        //判断验证码是否正确
        String captchaTem = (String) redisTemplate.opsForValue().get(uuid);
        if (captcha == null || !captcha.equals(captchaTem)) {
            throw new RRException("验证码错误");
        }
        //移除验证码 需要重新生成
        redisTemplate.opsForValue().getOperations().delete(uuid);
        UserEntity userEntity = userDao.findByAccount(phone);
        if (userEntity == null) {
            throw new RRException("账号:" + phone + "不存在!");
        }
        if (!userEntity.getPassword().equals(password)) {
            throw new RRException("账号密码不匹配");
        }
        return userEntity;
    }


    @Override
    public UserEntity loginByKaptcha(String phone, String uuid, String captcha) {
        //判断验证码是否正确
        String captchaTem = (String) redisTemplate.opsForValue().get(uuid);
        if (captcha == null || !captcha.equals(captchaTem)) {
            throw new RRException("验证码错误");
        }
        //移除验证码 需要重新生成
        redisTemplate.opsForValue().getOperations().delete(uuid);
        UserEntity userEntity = userDao.findByAccount(phone);
        if (userEntity == null) {
            throw new RRException("账号:" + phone + "不存在!");
        }
        return userEntity;
    }

    @Override
    public List<UserVO> getUserInfoList(Long[] userIds) {
        List<Long> list = Arrays.asList(userIds);
        List<UserVO> userlist = userDao.getUserList(list);
        return userlist;
    }

    @Override
    public UserVO getUser(Long userId) {
        UserEntity userEntity = userDao.get(userId);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userEntity, userVO);
        return userVO;
    }

    @Autowired
    private LevelService levelService;

    @Autowired
    private TokenService tokenService;

    @Override
    public List<UserBackVo> userList(Map<String, Object> params) {
        List<UserBackVo> list = new ArrayList<>();
        List<UserEntity> userEntities = userDao.userList(params);
        for (int i = 0; i < userEntities.size(); i++) {
            UserEntity userEntity = userEntities.get(i);
            UserBackVo userBackVo = new UserBackVo();
            if (userEntity.getParentId() == 0) {
                userBackVo.setParentName("自己");
                userBackVo.setParentId(0L);
            } else {
                UserEntity userEntity1 = userDao.findUserById(userEntity.getParentId());
                if (userEntity1 != null) {
                    userBackVo.setParentName(userEntity1.getName());
                    userBackVo.setParentId(userEntity1.getId());
                }
            }
            userBackVo.setId(userEntity.getId());
            userBackVo.setAvatar(userEntity.getAvatar());
            userBackVo.setName(userEntity.getName());
            userBackVo.setPhone(userEntity.getPhone());
            userBackVo.setInfo(userEntity.getInfo());
            userBackVo.setJoinTime(userEntity.getJoinTime());
            userBackVo.setLoginTime(userEntity.getLoginTime());
            userBackVo.setStatus(userEntity.getStatus());
            list.add(userBackVo);
        }
        return list;
    }
}
